package com.mp3.player.views
{
	import com.mp3.player.skins.defaultSkin.DefaultTrackInfoSkin;
	import com.mp3.player.vos.Track;
	
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.trace.Trace;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Image;
	import mx.core.UIComponent;
	import mx.styles.CSSStyleDeclaration;
	import mx.styles.StyleManager;
	
	import spark.components.Group;
	import spark.components.supportClasses.SkinnableComponent;
	
	/**
	 *Component that show information about mp3 track (atrist name, album, song name...). 
	 */	
	public class TrackInfo extends SkinnableComponent
	{
		/**
		 * @private
		 * This static function needs to set default styles to the component 
		 * without creating separate css file.
		 */
		private static function initializeStyles():void
		{
			var styles:CSSStyleDeclaration = StyleManager.getStyleManager(null).getStyleDeclaration("com.mp3.player.views.TrackInfo");
			if(!styles)
				styles = new CSSStyleDeclaration();
			
			styles.defaultFactory = function():void
			{	
				// default styles for the component
				this.skinClass = DefaultTrackInfoSkin;
			}
			StyleManager.getStyleManager(null).setStyleDeclaration("com.mp3.player.views.TrackInfo", styles, false);
		}
		initializeStyles();
		
		//--------------------------------------------------------------------------
		//
		//  Skin parts
		//
		//--------------------------------------------------------------------------		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the name Group. 
		 */
		public var nameGroup: Group;
		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the artist Group. 
		 */
		public var artistGroup: Group;
		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the track lenght Group. 
		 */
		public var lenghtGroup: Group;
		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the album name Group. 
		 */
		public var albumGroup: Group;
		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the album image. 
		 */
		public var albumImage: Image;
		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the genre Group. 
		 */
		public var genreGroup: Group;
		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the year Group. 
		 */
		public var yearGroup: Group;
		
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------		
		/**
		 * Track to show information about.
		 */		
		private var _track: Track;
		
		private var _change: Boolean = false;
		
		private var _parts: ArrayCollection = new ArrayCollection();
		/**
		 * Constructor
		*/
		public function TrackInfo()
		{
			super();
		}
		
		//----------------------------------------------------------------------------------------
		//
		// Life cyrcle
		//
		//----------------------------------------------------------------------------------------
		override protected function partAdded(partName:String, instance:Object):void
		{
			super.partAdded(partName, instance);
			
			switch(instance)
			{
				case albumImage:
					albumImage.addEventListener(Event.COMPLETE, onComplete);
					albumImage.addEventListener(IOErrorEvent.IO_ERROR, onFault);
					albumImage.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onFault);
					break;
			}
			
			if (!_parts.contains(instance))
			{
				_parts.addItem(instance);
				
				_change = true;
				invalidateProperties();
			}
		}
		
		override protected function partRemoved(partName:String, instance:Object):void
		{
			super.partRemoved(partName, instance);
			
			switch(instance)
			{
				case albumImage:
					albumImage.removeEventListener(Event.COMPLETE, onComplete);
					albumImage.removeEventListener(IOErrorEvent.IO_ERROR, onFault);
					albumImage.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onFault);
					break;
			}
			
			if (_parts.contains(instance))
			{
				_parts.removeItemAt(_parts.getItemIndex(instance));
				
				_change = true;
				invalidateProperties();
			}
		}
		
		override protected function commitProperties(): void
		{
			super.commitProperties();
			
			if (_change)
			{
				if (track == null)
				{
					for each (var ui: UIComponent in _parts)
					{
						ui.visible = false;
						ui.includeInLayout = false;
					}
				}
				else
				{
					var groupVisible: Boolean;
					
					groupVisible = (track.name != null && track.name != "");
					if (nameGroup)
					{
						nameGroup.visible = groupVisible;
						nameGroup.includeInLayout = groupVisible;
					}
					
					groupVisible = (track.artist != null && track.artist != "");
					if (artistGroup)
					{
						artistGroup.visible = groupVisible;
						artistGroup.includeInLayout = groupVisible;
					}
					
					groupVisible = (track.album != null && track.album != "");
					if (albumGroup)
					{
						albumGroup.visible = groupVisible;
						albumGroup.includeInLayout = groupVisible;
					}
					
					groupVisible = (!isNaN(track.length));
					if (lenghtGroup)
					{
						lenghtGroup.visible = groupVisible;
						lenghtGroup.includeInLayout = groupVisible;
					}
					
					
					groupVisible = (track.year != null && track.year != "");
					if (yearGroup)
					{
						yearGroup.visible = groupVisible;
						yearGroup.includeInLayout = groupVisible;
					}
					
					groupVisible = (track.genre != null && track.genre != "");
					if (genreGroup)
					{
						genreGroup.visible = groupVisible;
						genreGroup.includeInLayout = groupVisible;
					}
					
					groupVisible = (track.albumUrl != null && track.albumUrl != "");
					if (!groupVisible)
					{
						onFault();
					}
				}
			}
		}
		
		
		//----------------------------------------------------------------------------------------
		//
		// Properties
		//
		//----------------------------------------------------------------------------------------
		[Bindable("trackChanged")]
		public function get track(): Track
		{
			return _track;
		}
		public function set track(value: Track): void
		{
			_track = value;
			_change = true;
			invalidateProperties();
			dispatchEvent(new Event("trackChanged"));
		}

		private function onFault(event: Event = null): void
		{
			albumImage.includeInLayout = false;
			albumImage.visible = false;
		}
		
		private function onComplete(event: Event = null): void
		{
			albumImage.includeInLayout = true;
			albumImage.visible = true;
		}
	}
}